package org.ainlolcat.ainscience.metaentity;

import org.ainlolcat.aincalc2.MissingDependenciesException;
import org.ainlolcat.ainscience.Controller;
import org.ainlolcat.ainscience.UpdateListener;
import org.ainlolcat.ainscience.entity.Entity;
import org.ainlolcat.ainscience.templates.Template;
import org.ainlolcat.ainscience.tools;
import org.apache.log4j.Logger;
import org.jdom.Element;

import java.io.IOException;

/**
 * @author ainlolcat
 * Date: 10/29/11
 */
/**
 * decide which parser must be called and pass parameters to them
 */
public class MetaEntityFactory implements UpdateListener {
    private static Logger log = Logger.getLogger(MetaEntityFactory.class);
    Element definition;
    Template template;
    String entityType;
    String missingDependency;
    boolean inProgress = false;

    public MetaEntity load(Element e) throws IOException {
        definition = e;
        String templateName = definition.getAttributeValue("template");
        template = Controller.getInstance().getProject().getTemplateByName(templateName);
        entityType = e.getAttributeValue("entityType");
        return handleEntity();
    }

    private MetaEntity handleEntity(){
        Element entParse = template.getEntityParseParams(entityType);
        if (entParse.getAttributeValue("class")!=null){
            try {
                Class parser  = Class.forName(entParse.getAttributeValue("class"));
                MetaEntityParser handler = (MetaEntityParser) parser.newInstance();
                return handler.load(definition);
            } catch (MissingDependenciesException md) {
                missingDependency = md.getEntity();
                Controller.getInstance().addUpdateListener(this);
                throw md;
            } catch (IOException e) {
                throw new RuntimeException(e);
            } catch (ClassNotFoundException e) {
                throw new RuntimeException(e);
            } catch (InstantiationException e) {
                throw new RuntimeException(e);
            } catch (IllegalAccessException e) {
                throw new RuntimeException(e);
            }
        } else {
            return null;
        }
    }

    public void onProjectUpdate() {
        //To change body of implemented methods use File | Settings | File Templates.
    }

    public void onEntityUpdate(Entity entity, int action) {
        log.debug("Update event income for " + entity.getName());
        if (!inProgress && missingDependency != null && Controller.getInstance().getProject().getEntityByName(missingDependency) != null)
            try {
                log.debug("Process update event for missing dependencies " + missingDependency);
                inProgress = true;
                handleEntity();
                missingDependency = null;
            } catch (MissingDependenciesException md){
                log.debug("Still no luck");
                inProgress = false;
            }
    }
}
